import { Inject, Injectable } from '@nestjs/common';
import { RawImagerasterDto } from './dto/create-imageraster.dto';
import { UpdateImagerasterDto } from './dto/update-imageraster.dto';
import { Imageraster } from './entities/imageraster.entity';
import { Repository, In } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { FileList } from '../file-list/entities/file-list.entity';
import * as path from 'path';
import { spawn } from 'child_process';
import { WINSTON_LOGGER_TOKEN } from 'src/winston/winston.module';
import { PublicResource } from 'src/public_resource/entities/public_resource.entity';
@Injectable()
export class ImagerasterService {
  @Inject(WINSTON_LOGGER_TOKEN)
  private logger;

  constructor(
    @InjectRepository(Imageraster)
    private readonly imagerasterRepository: Repository<Imageraster>,
    @InjectRepository(FileList)
    private readonly fileListRepository: Repository<FileList>,
    @InjectRepository(PublicResource)
    private readonly publicResourceRepository: Repository<PublicResource>,
  ) {}
  async create(rawImagerasterDto: RawImagerasterDto) {
    const imageRaster = this.imagerasterRepository.create(rawImagerasterDto);
    const insertRes = await this.imagerasterRepository.insert(imageRaster);
    return insertRes.raw;
  }

  async createForScript(rawImagerasterDto: RawImagerasterDto) {
    const imageRaster = this.imagerasterRepository.create(rawImagerasterDto);
    const insertRes = await this.imagerasterRepository.insert(imageRaster);
    return insertRes.raw[0].id;
  }

  async findAll(): Promise<Imageraster[]> {
    return this.imagerasterRepository.find();
  }

  async findByIds(ids: string[]): Promise<Imageraster[]> {
    return this.imagerasterRepository.find({
      where: {
        id: In(ids), // 使用TypeORM的In操作符
      },
    });
  }

  async findOne(id: string): Promise<Imageraster> {
    return this.imagerasterRepository.findOne({ where: { id: id } });
  }

  async update(
    id: string,
    updateImagerasterDto: UpdateImagerasterDto,
    // file: Express.Multer.File,
  ) {
    const oldImageRaster = await this.imagerasterRepository.findOne({
      where: { id: id },
    });

    if (!oldImageRaster) {
      return '图片栅格条目不存在!';
    }
    const updatedImageraster = this.imagerasterRepository.merge(
      oldImageRaster,
      updateImagerasterDto,
    );

    await this.imagerasterRepository.save(updatedImageraster);
    return '修改图片栅格条目属性成功!';
  }

  async remove(id: string) {
    try {
      const result = await this.imagerasterRepository.delete({ id: id });

      if (result.affected && result.affected > 0) {
        return `成功删除 ${result.affected} 条记录`;
      } else {
        return `未找到匹配的记录，没有进行删除操作`;
      }
    } catch (err) {
      console.error('删除记录失败', err);
      throw '删除记录失败';
    }
  }

  async tif2png(file_path: string, output_path: string) {
    // const { spawn } = require('child_process');
    return new Promise((resolve, reject) => {
      const pythonProcess = spawn('python', [
        `${process.env.PYTHON_PATH}/tif2png.py`,
        file_path,
        output_path,
      ]);
      let result = '';
      let errorOutput = ''; // 用于存储错误输出信息

      pythonProcess.stdout.on('data', (data) => {
        result += data.toString();
      });

      pythonProcess.stderr.on('data', (data) => {
        errorOutput += data.toString();
      });

      pythonProcess.on('close', (code) => {
        if (code === 0) {
          this.logger.log(`Python脚本成功执行:`);
          resolve(result); // 成功执行时返回结果
        } else {
          this.logger.log(`Python脚本执行出错，退出码：${code}`);
          this.logger.log(`Python脚本错误输出：${errorOutput}`);
          console.error(`Python脚本执行出错，退出码：${code}`);
          console.error(`Python脚本错误输出：${errorOutput}`);
          reject(
            `Python脚本执行出错，退出码：${code}, 错误输出：${errorOutput}`,
          ); // 执行出错时返回错误信息
        }
      });
    });
  }

  async getImageRasterbbox(id: string) {
    const fileItem = await this.fileListRepository.findOne({
      where: { id: id },
    });
    const file_path = path.resolve(
      `${process.env.FILE_PATH}/${fileItem.uploader}/imageraster/${fileItem.src}`,
    );
    const bbox = await new Promise((resolve, reject) => {
      const pythonProcess = spawn('python', [
        `${process.env.PYTHON_PATH}/getImagerasterbbox.py`,
        file_path,
      ]);
      let result = '';
      let errorOutput = ''; // 用于存储错误输出信息

      pythonProcess.stdout.on('data', (data) => {
        result += data.toString();
      });

      pythonProcess.stderr.on('data', (data) => {
        errorOutput += data.toString();
      });

      pythonProcess.on('close', (code) => {
        if (code === 0) {
          console.log('Python脚本成功执行');
          resolve(result); // 成功执行时返回结果
        } else {
          console.error(`Python脚本执行出错，退出码：${code}`);
          console.error(`Python脚本错误输出：${errorOutput}`);
          reject(
            `Python脚本执行出错，退出码：${code}, 错误输出：${errorOutput}`,
          ); // 执行出错时返回错误信息
        }
      });
    });
    return String(bbox)
      .substring(0, String(bbox).length - 4)
      .split(',')
      .map(Number);
  }

  async getPubilcImageRasterbbox(id: string) {
    const fileItem = await this.publicResourceRepository.findOne({
      where: { id: id },
    });
    const file_path = path.resolve(
      `${process.env.FILE_PATH}/public/imageraster/${fileItem.src}`,
    );
    const bbox = await new Promise((resolve, reject) => {
      const pythonProcess = spawn('python', [
        `${process.env.PYTHON_PATH}/getImagerasterbbox.py`,
        file_path,
      ]);
      let result = '';
      let errorOutput = ''; // 用于存储错误输出信息

      pythonProcess.stdout.on('data', (data) => {
        result += data.toString();
      });

      pythonProcess.stderr.on('data', (data) => {
        errorOutput += data.toString();
      });

      pythonProcess.on('close', (code) => {
        if (code === 0) {
          console.log('Python脚本成功执行');
          resolve(result); // 成功执行时返回结果
        } else {
          console.error(`Python脚本执行出错，退出码：${code}`);
          console.error(`Python脚本错误输出：${errorOutput}`);
          reject(
            `Python脚本执行出错，退出码：${code}, 错误输出：${errorOutput}`,
          ); // 执行出错时返回错误信息
        }
      });
    });
    return String(bbox)
      .substring(0, String(bbox).length - 4)
      .split(',')
      .map(Number);
  }
}
